import numpy as np
import pandas as pd
from get_data.origin_data import *

# 行列对齐(打印调试用)
# pd.set_option('display.unicode.ambiguous_as_wide', True)
# pd.set_option('display.unicode.east_asian_width', True)
# pd.set_option('display.width', None)
# pd.set_option('display.max_rows', None)
# pd.set_option('display.max_columns', None)

# 获取开始日期
def start_date(df_basic):
    df = df_basic.copy()

    date = df.iloc[0, 0]
    return date

# 获取结束日期
def end_date(df_basic):
    df = df_basic.copy()

    date = df.iloc[-1, 0]
    return date

# 计算年化收益率
def ARR(df_basic):
    df = df_basic.copy()

    arr = df.iloc[-1, -1] ** (252 / len(df)) - 1

    return arr

# 计算年化超额收益率
def excess_ARR(df_basic):

    df = df_basic.copy()

    # 计算累计超额净值
    df['累积超额净值'] = df['累积净值'] / df['指数净值']

    arr = df.iloc[-1, -1] ** (252 / len(df)) -1

    return arr

# 计算持有期占比
def holding_period_pct(df_basic):
    df = df_basic.copy()

    df = df.iloc[:, -3]
    holding_period = np.sum(df)
    all_period = len(df)
    pct = holding_period / all_period
    return pct

# 计算进场次数
def decision_time(df_basic):
    df = df_basic.copy()

    df['持有起始'] = np.nan

    if df.iloc[0, -4] == 1 and df.iloc[1, -4] == 1:
        df.iloc[0, -1] = 1

    for i in range(1, len(df) - 1):
        if df.iloc[i, -4] == 0 and df.iloc[i + 1, -4] == 1:
            df.iloc[i, -1] = 1

        if df.iloc[i, -4] == 1 and df.iloc[i + 1, -4] == 0:
            df.iloc[i, -1] = 0

    df = df.dropna()
    dec_time = np.sum(df['持有起始'])
    return dec_time

# 计算看多择时胜率
def win_rate(df_basic):
    df = df_basic.copy()

    holding_period = decision_time(df)

    df['持有起始'] = np.nan

    if df.iloc[0, -4] == 1 and df.iloc[1, -4] == 1:
        df.iloc[0, -1] = 1

    for i in range(1, len(df) - 1):
        if df.iloc[i, -4] == 0 and df.iloc[i + 1, -4] == 1:
            df.iloc[i, -1] = 1

        if df.iloc[i, -4] == 1 and df.iloc[i + 1, -4] == 0:
            df.iloc[i, -1] = 0

    last_value = df.iloc[-1, -2]

    df = df.dropna().reset_index(drop=True)

    df['是否获胜'] = np.nan

    if len(df) % 2 == 0:
        for i in range(len(df) - 1):
            if df.iloc[i, -2] == 1 and df.iloc[i + 1, -2] == 0:
                df.iloc[i + 1, -1] = (df.iloc[i + 1, -3] > df.iloc[i, -3]).astype(int)
    else:
        for i in range(len(df) - 2):
            if df.iloc[i, -2] == 1 and df.iloc[i + 1, -2] == 0:
                df.iloc[i + 1, -1] = (df.iloc[i + 1, -3] > df.iloc[i, -3]).astype(int)
            df.iloc[-1, -1] = (last_value >= df.iloc[-1, -3]).astype(int)

    win = np.sum(df['是否获胜'])

    win_rate = win / holding_period

    return win_rate

# 计算多空择时胜率
def buy_sell_win_rate(df_basic):


    # 获取看多择时胜利次数
    def buy_win_time(df_basic):
        df = df_basic.copy()

        df['持有期起始'] = np.nan

        if df.iloc[0, -4] == 1 and df.iloc[1, -4] == 1:
            df.iloc[0, -1] = 1

        for i in range(1, len(df) - 1):
            if df.iloc[i, -4] == 0 and df.iloc[i + 1, -4] == 1:
                df.iloc[i, -1] = 1

            if df.iloc[i, -4] == 1 and df.iloc[i + 1, -4] == 0:
                df.iloc[i, -1] = 0

        last_value = df.iloc[-1, -2]

        df = df.dropna().reset_index(drop=True)

        df['是否获胜'] = np.nan

        if len(df) % 2 == 0:
            for i in range(len(df) - 1):
                if df.iloc[i, -2] == 1 and df.iloc[i + 1, -2] == 0:
                    df.iloc[i + 1, -1] = (df.iloc[i + 1, -3] >= df.iloc[i, -3]).astype(int)
        else:
            for i in range(len(df) - 2):
                if df.iloc[i, -2] == 1 and df.iloc[i + 1, -2] == 0:
                    df.iloc[i + 1, -1] = (df.iloc[i + 1, -3] >= df.iloc[i, -3]).astype(int)
                df.iloc[-1, -1] = (last_value >= df.iloc[-1, -3]).astype(int)

        win = np.sum(df['是否获胜'])
        return win

    # 获取看空择时胜利次数
    def sell_win_time(df_basic):
        df = df_basic.copy()

        df['持有起始'] = np.nan

        if df.iloc[0, -4] == 0 and df.iloc[1, -4] == 0:
            df.iloc[0, -1] = 0

        for i in range(1, len(df) - 1):
            if df.iloc[i, -4] == 0 and df.iloc[i + 1, -4] == 1:
                df.iloc[i, -1] = 1

            if df.iloc[i, -4] == 1 and df.iloc[i + 1, -4] == 0:
                df.iloc[i, -1] = 0

        last_value = df.iloc[-1, 1]

        df = df.dropna().reset_index(drop=True)

        df['是否获胜'] = np.nan

        if len(df) % 2 == 0:
            for i in range(len(df) - 1):
                if df.iloc[i, -2] == 0 and df.iloc[i + 1, -2] == 1:
                    df.iloc[i + 1, -1] = (df.iloc[i + 1, 1] <= df.iloc[i, 1]).astype(int)  # 备注：修改大小于号
        else:
            for i in range(len(df) - 2):
                if df.iloc[i, -2] == 0 and df.iloc[i + 1, -2] == 1:
                    df.iloc[i + 1, -1] = (df.iloc[i + 1, 1] <= df.iloc[i, 1]).astype(int)  # 备注：修改大小于号
                df.iloc[-1, -1] = (last_value >= df.iloc[-1, 1]).astype(int)

        win = np.sum(df['是否获胜'])

        return win

    # 获取出场次数
    def escape_time(df_basic):
        df = df_basic.copy()

        df['退场时点'] = np.nan

        for i in range(len(df) - 1):
            if df.iloc[i, -4] == 1 and df.iloc[i + 1, -4] == 0:  # 备注：修改0，1位置
                df.iloc[i, -1] = 1
            else:
                df.iloc[i, -1] = 0

        return np.sum(df['退场时点'])

    win_time = buy_win_time(df_basic) + sell_win_time(df_basic)

    all_time = decision_time(df_basic) + escape_time(df_basic)

    return win_time / all_time

def max_drawback(df_basic):
    df = df_basic.copy()

    df['回撤'] = 0

    for i in range(1, len(df)):
        df.loc[i, '回撤'] = df.loc[i, '累积净值'] / np.max(df.loc[0:i, '累积净值']) - 1

    maxdrawdown_rate = -np.min(df['回撤'])

    return maxdrawdown_rate

# 计算超额最大回撤
def excess_max_drawback(df_basic):
    df = df_basic.copy()

    # 计算累计超额净值
    df['累积超额净值'] = df['累积净值'] / df['指数净值']

    df['回撤'] = 0

    for i in range(1, len(df)):
        df.loc[i, '回撤'] = df.loc[i, '累积超额净值'] / np.max(df.loc[0:i, '累积超额净值']) - 1

    maxdrawdown_rate = -np.min(df['回撤'])

    return maxdrawdown_rate

def indicator_merge(df_basic):
    df = df_basic.copy()

    dic = {'开始日期':start_date(df), '结束日期':end_date(df), '年化收益率':ARR(df), '年化超额收益率':excess_ARR(df), '持有期占比':holding_period_pct(df), '进场次数':decision_time(df),
           '看多择时胜率':win_rate(df), '多空总择时胜率':buy_sell_win_rate(df), '期间最大回撤':max_drawback(df), '超额最大回撤':excess_max_drawback(df)}

    df = pd.DataFrame({'评价指标':list(dic.keys()), '值':list(dic.values())})

    return df

def massive_indictor():
    ls = ['RSJ_5D', 'RSJ_10D', 'covprice_mid', 'covtend', 'covskew', 'cov_+ret_pct_5D', 'IVdelta_mid_5D',
          'IVdelta_mid_22D', 'YTMdelta_mid', 'covpremium_mid', 'covpremium_modified_mid', 'stock_bondpremium_mid',
          'IVnan_pct']
    ls_el = ['Roll', 'MACD', 'SMA', '八均线', '多头排列']
    df_all = pd.DataFrame()

    for type in ls:
        for cate in ls_el:
            df = pd.read_excel(f'因子回测结果\\{type}回测.xlsx', sheet_name=f'{cate}')
            df = indicator_merge(df)
            df = df.T
            df.columns = df.iloc[0, :]
            df = df.iloc[1:, :]
            df.index = [f'{type} {cate}']
            df_all = pd.concat([df_all, df])

    df_all.to_excel('因子评价指标/各因子评价指标.xlsx')

